/*
 *      wall.cpp
 *      
 *      Copyright 2008 Víctor Manuel Ochoa <kanito8a@gmail.com>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */


#include "wall.h"

/*
 * 
 * name * @param
 * @return
 */
Wall::Wall(){
  m_pLog=&Log::getInstance();
  m_BlocksSize=0.1;
  m_LinesNumber=MAX_BLOCKS_LINES;
  m_BlocksPerLineNumber=MAX_BLOCKS_PER_LINE; 
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
Wall::~Wall(){
  
}

/*
 * 
 * name: init
 * Initializes the class
 * @param *_fileName
 * @return bool True if the initializing goes ok
 */
bool Wall::init(const char *_fileName){
  if(!m_Texture.init(_fileName)){
    m_pLog->error("Unable to init Wall. Invalid Texture: ",_fileName);
    return false;    
  }
  
  for(int line=0;line<MAX_BLOCKS_LINES;line++){
    for(int block=0;block<MAX_BLOCKS_PER_LINE;block++){
      m_Wall[line][block].blockTexture=&m_Texture;
      m_Wall[line][block].blockColor[0]=1.0f;
      m_Wall[line][block].blockColor[1]=1.0f;
      m_Wall[line][block].blockColor[2]=1.0f;
      m_Wall[line][block].blockType=0;
      if(line<block){
        m_Wall[line][block].active=true;  
      }
      else{
        m_Wall[line][block].active=false;  
      }
      
    }
  }
  m_pLog->debug((const char *)"+ Wall initialized");
  return true;
}

/*
 * 
 * name: draw
 * Draws the wall
 * @param N/A
 * @return void
 */
void Wall::draw(){  
  glDisable( GL_BLEND );  
  for(int i=0;i<m_LinesNumber;i++){
    for(int j=0;j<m_BlocksPerLineNumber;j++){
      if(m_Wall[i][j].active){
        drawBlock(&m_Wall[i][j],(j*m_BlocksSize*2)-(1-m_BlocksSize),(i*m_BlocksSize)-(1-m_BlocksSize/2),0,m_BlocksSize);
      }
    }
  }
}

/*
 * 
 * name: drawBlock
 * Draws a single block of the wall.
 * @param *_block Block to draw
 * @param _x,_y,_z Block coords
 * @param _sizeMod Size modificator of the block
 * @return void
 */
void Wall::drawBlock(const Block *_block,
                      float _x,
                      float _y,
                      float _z,
                      float _sizeMod){
  glPushMatrix(); 
  glTranslatef(_x,_y,_z); 
  _block->blockTexture->bind();
  
  glColor3f(_block->blockColor[0],_block->blockColor[1],_block->blockColor[2]);
 
  glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.333f, 0.0f); glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.333f, 0.5f); glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.0f, 0.5f);   glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod);  
    // Back Face
    glTexCoord2f(0.333f, 0.5f); glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod, 1.0f*_sizeMod); 
    glTexCoord2f(0.0f, 0.5f);   glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod, 1.0f*_sizeMod); 
    glTexCoord2f(0.0f, 1.0f);   glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod, 1.0f*_sizeMod); 
    glTexCoord2f(0.333f, 1.0f); glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod, 1.0f*_sizeMod);
    // Top Face
    glTexCoord2f(0.333f, 0.5f); glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod,  1.0f*_sizeMod);
    glTexCoord2f(0.666f, 0.5f); glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod,  1.0f*_sizeMod);
    glTexCoord2f(0.666f, 1.0f); glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);
    glTexCoord2f(0.333f, 1.0f); glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);
    // Bottom Face
    glTexCoord2f(0.666f, 1.0f); glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod,  1.0f*_sizeMod); 
    glTexCoord2f(1.0f, 1.0f);   glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod,  1.0f*_sizeMod); 
    glTexCoord2f(1.0f, 0.5f);   glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod); 
    glTexCoord2f(0.666f, 0.5f); glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod); 
    // Right face
    glTexCoord2f(1.0f, 0.0f);   glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod,  1.0f*_sizeMod);  
    glTexCoord2f(0.666f, 0.0f); glVertex3f( 1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.666f, 0.5f); glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(1.0f, 0.5f);   glVertex3f( 1.0f*_sizeMod, -0.5f*_sizeMod,  1.0f*_sizeMod);  
    // Left Face
    glTexCoord2f(0.33f, 0.5f); glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod,  1.0f*_sizeMod);  
    glTexCoord2f(0.66f, 0.5f); glVertex3f(-1.0f*_sizeMod, -0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.66f, 0.0f); glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod, -1.0f*_sizeMod);  
    glTexCoord2f(0.33f, 0.0f); glVertex3f(-1.0f*_sizeMod,  0.5f*_sizeMod,  1.0f*_sizeMod);  
  glEnd();  
  
  glPopMatrix();
}


